package cn.buk.tms.eotms.service;

import cn.buk.api.pay.alipay.service.AlipayService;
import cn.buk.common.JsonResult;
import cn.buk.common.util.DateUtil;
import cn.buk.tms.common.constant.TmsOrderConstant;
import cn.buk.tms.common.dto.base.BaseDto;
import cn.buk.tms.eotms.dao.CarOrderDao;
import cn.buk.tms.eotms.dao.OrderNoGenerator;
import cn.buk.tms.eotms.dao.PaymentOrderDao;
import cn.buk.tms.eotms.dto.CarOrderDto;
import cn.buk.tms.eotms.dto.RoleInfo;
import cn.buk.tms.eotms.entity.*;
import cn.buk.tms.eotms.sc.SearchCarOrderCriteria;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static cn.buk.tms.common.constant.TmsOrderConstant.*;

/**
 * 租车功能服务类
 * @author yfdai
 */
@Component
public class RentalCarServiceImpl extends BaseAbstractService implements RentalCarService {

    private static final Logger logger = Logger.getLogger(RentalCarServiceImpl.class);

    @Autowired
    public RentalCarServiceImpl(CarOrderDao carOrderDao,
                                OrderNoGenerator orderNoGenerator,
                                PaymentOrderDao paymentOrderDao,
                                AlipayService alipayService,
                                @Value("${owner_enterprise_id}") int ownerId) {
        this.carOrderDao = carOrderDao;
        this.orderNoGenerator = orderNoGenerator;
        this.paymentOrderDao = paymentOrderDao;
        this.alipayService = alipayService;
        this.ownerId = ownerId;
    }

    private final OrderNoGenerator orderNoGenerator;
    private final CarOrderDao carOrderDao;
    private final PaymentOrderDao paymentOrderDao;
    private final AlipayService alipayService;
    private final int ownerId;

    /**
     * 根据供应商的车型ID查找本地映射的车型名称
     * @param ownerId
     * @param vehicleTypeId
     * @return
     */
    private VehicleGroupMapping getVehicleMappingBySupplierVehicleId(final int ownerId, final int vehicleTypeId) {
        List<ProductDefaultSupplier> suppliers = enterpriseDao.searchApiProductSupplier(ownerId);
        suppliers = suppliers.stream().filter(t -> t.getProductType() == PRODUCT_TYPE_DOM_CAR).collect(Collectors.toList());
        if (suppliers.isEmpty()) {
            return null;
        }

        for(ProductDefaultSupplier supplier: suppliers) {
            List<VehicleGroupMapping> vehicleMappings = enterpriseDao.searchVehicleGroupMappings(ownerId, supplier.getSupplier().getId());
            for(VehicleGroupMapping mapping: vehicleMappings) {
                if (mapping.getSupplierVehicleGroupId() == vehicleTypeId) {
                    return mapping;
                }
            }
        }

        return null;
    }


    @Override
    public BaseDto submitCarOrder(final int userId, String orderNo, int vehicleTypeId, String vehicleTypeName,
                                  double price, double discount, String linkPhone, String linkman, String email, int payType, String remark, int flightOrderId) {
        final int ownerId = getOwnerIdByUserId(userId);

        BaseDto dto = new BaseDto();
        dto.setErrcode(0);
        try {
            //获取本地的车型组id
            VehicleGroupMapping mapping = getVehicleMappingBySupplierVehicleId(ownerId, vehicleTypeId);
            if (mapping == null) {
                dto.setErrcode(404);
                dto.setErrmsg("未找到车型信息");
                return dto;
            }
            int supplierVehicleTypeId = mapping.getSupplierVehicleGroupId();
            int retCode = carOrderDao.submitRentalCarOrder(ownerId, userId, orderNo,
                    vehicleTypeId, vehicleTypeName, supplierVehicleTypeId,
                    price, discount, linkPhone, linkman, email, payType, remark, flightOrderId);
            dto.setReturnCode(retCode);
        } catch (RuntimeException ex) {
            dto.setErrcode(-100);
            dto.setErrmsg(ex.getMessage());
        }

        return dto;
    }

    @Override
    public List<CarOrderDto> searchRentalCarOrders(final int userId, SearchCarOrderCriteria sc) {
        final int ownerId = getOwnerIdByUserId(userId);
        final int customerId = getCustomerIdByUserId(userId);
        final int enterpriseId = getEnterpriseIdByUserId(userId);
        final String username = getUsernameByUserId(userId);

        Set<String> roles = getRolesByUserId(enterpriseId, userId);
        //管理员可以查看所有的员工信息
        //其它可以查看本部门所有的员工信息
        if (roles.contains(RoleInfo.ROLE_ADMIN)) {
            //管理员可以查看所有部门的订单
        } else if (roles.contains(RoleInfo.ROLE_MANAGER) || roles.contains(RoleInfo.ROLE_APPROVER)){
            //只能查看本部门的
            int deptId = getCustomerDeptIdByUserId(userId);
            sc.setDepartmentId(deptId);
        } else {
            //只能查看自己的订单
            sc.setOp1(username);
        }

        List<RentalCarOrder> orders = carOrderDao.searchOrders(ownerId, customerId, sc);

        List<CarOrderDto> dtos = new ArrayList<>();

        for (RentalCarOrder order : orders) {
            CarOrderDto dto = CarOrderDto.createByRentalCarOrder(order);
            dtos.add(dto);
        }

        return dtos;
    }

    @Override
    public CarOrderDto searchRentalCarOrder(final int userId, final int orderId) {
        final int ownerId = getOwnerIdByUserId(userId);
        final int customerEnterpriseId = getEnterpriseIdByUserId(userId);

        RentalCarOrder order = carOrderDao.getOrderById(orderId);

        if (order == null || order.getEnterpriseId() != ownerId || order.getCustomerEnterpriseId() != customerEnterpriseId) {
            throw new RuntimeException("RentalCar order(" + orderId + ") is not existed.");
        }

        CarOrderDto dto =  CarOrderDto.createByRentalCarOrder(order);
        dto.setErrcode(0);
        return dto;
    }

    @Override
    public JsonResult cancelRentalCarOrder(int userId, int orderId) {

        return JsonResult.createJsonResult(-10, "暂时无法取消该订单，请联系客服");

//        final int ownerId = getOwnerIdByUserId(userId);
//        final int customerId = getCustomerIdByUserId(userId);
//        final String username = getUsernameByUserId(userId);
//
//        try {
//            return JsonResult.createJsonResult(
//                    carOrderDao.cancelRentalCarOrder(ownerId, customerId, username, orderId));
//
//        } catch (RuntimeException ex) {
//            return JsonResult.createJsonResult(-100, ex.getMessage());
//        }
    }

  @Override
  public JsonResult payRentalCarOrder(final int userId, final int orderId) {
      CarOrderDto orderDto = this.searchRentalCarOrder(userId, orderId);
      if (orderDto == null) {
          return JsonResult.createJsonResult(-1, "无此订单");
      }

      if (orderDto.getPayType() != PAY_TYPE_CASH) {
          return JsonResult.createJsonResult(-1, "该订单的付款方式非现金方式");
      }

      if (orderDto.getOrderStatus() != RENTAL_CAR_ORDER_STATUS_WAITING &&
              orderDto.getOrderStatus() != RENTAL_CAR_ORDER_STATUS_PROCESSING
      ) {
          return JsonResult.createJsonResult(-1, "该订单的暂时不能付款");
      }




      final int enterpriseId = getEnterpriseIdByUserId(userId);
      final int ownerId = getOwnerIdByUserId(userId);

      //支付订单号
      // 10 - 支付宝支付
      // 20 - 表示微信支付
      String outTradeNo = "10"+ enterpriseId + "0" + + userId + "0" + DateUtil.getCurDateTimeString("yyyyMMddHHmmss");
      //商户网站订单系统中唯一订单号，必填

      //订单名称
      final String subject = "租车订单付款";
      //必填

      //保存支付订单
      PaymentOrder order = new PaymentOrder();
      order.setEnterpriseId(enterpriseId);
      order.setUserId(userId);
      order.setOwnerEnterpriseId(ownerId);
      order.setTradeNo(outTradeNo);
      order.setPrice(orderDto.getTotalAmount());
      order.setStatus(0);
      order.setMemo(subject);
      order.setOrderType(ORDER_TYPE_CAR);
      order.setOrderId(orderId);

      JsonResult jsonResult = new JsonResult();

      jsonResult.setStatus("OK");
      paymentOrderDao.create(order);

      String url = alipayService.createPaymentParams(outTradeNo, orderDto.getTotalAmount(), subject);

      logger.info(url);

      jsonResult.setUrl(url);

      return jsonResult;
  }

  @Override
  public JsonResult approveRentalCarOrder(int userId, int orderId, int denyCode, String denyReason) {
      if (denyCode != 0 && (denyReason == null || denyReason.trim().length() < 3 )) {
          return JsonResult.createJsonResult(-1, "请输入拒绝的原因");
      }
      final int ownerId = getOwnerIdByUserId(userId);
      final int customerId = getCustomerIdByUserId(userId);

      RentalCarOrder rentalCarOrder = carOrderDao.getOrderById(orderId);
      if (customerId != rentalCarOrder.getCustomer().getId()) {
          return JsonResult.createJsonResult(-2, "订单不存在");
      }

      //判断审批人是否有权审批
      //1.是指定的审批人
      final String username = getUsernameByUserId(userId);
      if (rentalCarOrder.getApprovalInfo() != null &&
              username.equalsIgnoreCase(rentalCarOrder.getApprovalInfo().getSpecifiedApprover())) {

          int retCode = carOrderDao.approveRentalCarOrder(ownerId, customerId, username, orderId, denyCode, denyReason);
          return JsonResult.createJsonResult(retCode);
      } else {
          return JsonResult.createJsonResult(-1, "您不是指定审批人");
      }

      //TODO
      //2.如果不是，就是部门审批人
      //3.如果不是，就是主账户
      //4.都不是，提示无权审批


//    return null;
  }

  /**
     * 保存租车订单（询价状态）
     *
     * @param dto
     */
    private void doSaveRentalCarOrder(final int userId, CarOrderDto dto) {
        final int ownerId = getOwnerIdByUserId(userId);
        final int customerId = getCustomerIdByUserId(userId);
        final int customerEnterpriseId = getEnterpriseIdByUserId(userId);
        final String username = getUsernameByUserId(userId);

        if (customerId <= 0) {
            throw new RuntimeException("未找到当前用户的customerId");
        }

        RentalCarOrder orderInfo = new RentalCarOrder();
        BeanUtils.copyProperties(dto, orderInfo);

        orderInfo.setEnterpriseId(ownerId);
        orderInfo.setCustomerEnterpriseId(customerEnterpriseId);
        orderInfo.setOperator(username);
        orderInfo.setCityName(dto.getCityName());

        orderInfo.setCustomerType(1);
        Customer c = new Customer();
        c.setId(customerId);
        orderInfo.setCustomer(c);

        //保存供应商订单号
        orderInfo.setSupplierOrderNo(dto.getOrderNo());


        //订单号
        orderInfo.setOrderNo(orderNoGenerator.generateOrderNo(ownerId, TmsOrderConstant.ORDER_NO_RENTAL_CAR_SELF_SERVICE));
//        orderInfo.setDepartureLongitude(dto.getDepartureLocation().getLongitude());
//        orderInfo.setDepartureLatitude(dto.getDepartureLocation().getLatitude());
//        orderInfo.setArrivalLongitude(dto.getArrivalLocation().getLongitude());
//        orderInfo.setArrivalLatitude(dto.getArrivalLocation().getLatitude());

        carOrderDao.createCarOrder(orderInfo);

        //用本地订单号显示给调用者
        dto.setOrderNo(orderInfo.getOrderNo());
    }


}
